本系列將介紹 Rails with Vue 的基本概念,並且以一個簡單的專案 Todo 來說明如何使用 Rails with Vue。我將透過這一系列的文章記錄我學習的過程,並且將我所學到的知識分享給大家。
- 【Day 01】淺入淺出 Rails with Vue - Before We Begin
- 【Day 02】淺入淺出 Rails with Vue - Vue 的基本概念 - 1
- 【Day 03】淺入淺出 Rails with Vue - Vue 的基本概念 - 2
- 【Day 04】淺入淺出 Rails with Vue - Vue 的基本概念 - 3
- 【Day 05】淺入淺出 Rails with Vue - Vue 的基本概念 - 4
- 【Day 06】淺入淺出 Rails with Vue - Vue 的基本概念 - 5
- 【Day 07】淺入淺出 Rails with Vue - Vue 的基本概念 - 6
- 【Day 08】淺入淺出 Rails with Vue - Vue 的基本概念 - 7
- 【Day 09】淺入淺出 Rails with Vue - Vue 的基本概念 - 8
- 【Day 10】淺入淺出 Rails with Vue - Vue 的基本概念 - 9
- 【Day 11】淺入淺出 Rails with Vue - Vue 的基本概念 - 10
- 【Day 12】淺入淺出 Rails with Vue - Vue 的基本概念 - 11
- 【Day 13】淺入淺出 Rails with Vue - Vue 的基本概念 - 12
- 【Day 14】淺入淺出 Rails with Vue - Vue 的基本概念 - 13
- 【Day 15】淺入淺出 Rails with Vue - Vue 的基本概念 - 14
- 【Day 16】淺入淺出 Rails with Vue - Vue 的基本概念 - 15
- 【Day 17】淺入淺出 Rails with Vue - Vue 的基本概念 - 16
Component 是一個可以重複使用的 Vue 實例,可以將它想像成一個自定義的 HTML 標籤,並且可以在這個標籤中傳入參數,並且在這個標籤中使用這些參數。
// Define a new component called button-counter
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
例如以上範例中,我們定義了一個名為 button-counter
的 Component,我們可以在 root Vue 實例中 new Vue
使用這個 Component
<div id="components-demo">
<button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })
因為 Component 為可重複使用的 Vue 實例,他們可以接受像是 new Vue
的參數,例如 data
、computed
、watch
、methods
等等。
Component 可以根據需要多次重複使用,例如以下範例中,我們定義了一個名為 button-counter
的 Component,並且在 root Vue 實例中使用了 3 次。
這 3 個 Component 會各自維護自己的 data
,因為他們是來自 3 個不同的 Vue 實例,彼此獨立運作。
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
data
Must Be a Function在建立 button-counter
Component 時,你可能已經注意到 data
沒有透過 object 的方式傳入,如以下的寫法:
data: {
count: 0
}
取而代之的是,data
必須是一個 function,透過 function 的方式回傳一個 object,這樣才能保證每個 Component 都有自己的 data
。
data: function () {
return {
count: 0
}
}
假如上面例子中不是透過 function 的方式回傳 data
,那麼所有的 Component 都會共用同一個 data
,這樣就會造成所有的 Component 都會共用同一個 count
,這樣就不是我們想要的結果。
將應用程式 (APP) 拆分成一個個小的 Component,這樣可以讓程式碼更容易維護,也可以讓程式碼更容易重複使用。
舉例來說,你可能有 header、sidebar、content 這 3 個 Component,每個 Component 可能又包含在自己的 Component 中,例如 header 可能包含了 logo、navigation、search 這 3 個 Component。
要在 template 中使用這些 Component,必須要先在 Vue 實例中註冊這些 Component,這樣 Vue 才能夠知道這些 Component 的存在。
現行兩種註冊 Component 的方式,分別是全域註冊 (Global Registration) 與區域註冊 (Local Registration)。
到目前為止我們都是透過全域註冊的方式來註冊 Component,例如:
Vue.component('my-component-name', {
// ... options ...
})
全域註冊可以使用在任何 root Vue 實例 (new Vue) 中,甚至在 subcomponents 中也可以使用。
在先前我們提到為一個 blog 的 posts 建立一個 Component,那時候遇到的問題是,component 無法取得 posts 相關的資料,因為 posts 是在 root Vue 實例中定義的,而 component 是在 root Vue 實例中使用的。
為了解決這個問題,我們可以透過 props
來傳遞資料給 child component。props
是一個自定義的 attribute,你可以在 component 中像是使用 data
一樣使用 props
。當 value 被傳遞給一個 prop attribute 時,它就變成了該 component 實例的一個 property。
例如在以下的範例中,我們定義了一個名為 blog-post
的 component,並且可以透過 props
來傳遞一個 title
的 attribute 給這個 component。
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
一個 Component 可以有任意數量的 prop,只要在 props
中定義即可,一但 prop 被定義,你可以傳遞任意的 string 作為 prop 的 attribute,如以下範例:
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
將會渲染為
<div id="blog-post-demo" class="demo">
<h3>My journey with Vue</h3>
<h3>Blogging with Vue</h3>
<h3>Why Vue is so fun</h3>
</div>
然而人類是貪心的,總是想要更多,上面的範例中只傳送了 String,但是很多時候我們想傳送的是 Array 或是 Object,
如以下範例中,我們想要傳送一個包含了 id
、title
的 Array 給 blog-post
component。
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
})
然後想要渲染為
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>
在以上的範例中,我們使用了 v-bind
指令來動態的傳遞 title
的 attribute 給 blog-post
component,當你不太確定實際上要渲染的內容是什麼時,這樣的方法是很有用的,就很像 fetch data from api 一樣,你不知道實際上會拿到什麼,但是你知道你會拿到什麼。